/*
 * Chrome plugin to manage Google Bookmarks
 *
 * @see https://code.google.com/p/google-bookmarks-plugin
 *
 * Copyright (c) 2013, Shakil Siraj(shakil.siraj@gmail.com). Licensed MIT.
 */



/*Constants*/
var unsorted = "";

/*Google login page*/
var GOOGLE_LOGIN_URL = "https://www.google.com";

var GOOGLE_BOOKMARK_URL = "https://www.google.com/bookmarks/";

/*Refernce to the labels map*/
var lebelsMap;

/*Reference to the bookmarks signature*/
var signature;

/*Indicator for bookmakr tab to understand*/
var bookmarkEdit = false;

/*Reference to bookmark json object array*/
var bookmarks = [];

/*Reference to the current bookmark that is being edited*/
var currentBookmark;

/*Reference to the last error with AJAX*/
var lastError;

function log(message){
	console.log(message);
}

$(document).ready(
	setTimeout(
		function(){
			//$('#loadingInfo').show();
			startExtension();
		},
		1
	)
)

function startExtension(){
 	$.ajaxSetup({
 		timeout: 30000,
  		beforeSend: function() {
     		$('#loadingInfo').show();
  		},
  		complete: function(){
     		$('#loadingInfo').hide();
  		},
  		success: function() {

  		},
  		error : function(jqXHR, textStatus, errorThrown) {
        	lastError = {status:jqXHR.status,exception:errorThrown};
        	log("Error happend! ");
        	log(lastError);
        	$("#tabs").hide();
        	$('#loadingFailure').show();
    	}
	});
	downloadBookmarks();
	//assignButtons();
	// createContextMenu();
	assignButtonListeners();
}

function assignButtonListeners(){

	$('#btnAddBookmark').click(
		function(e){
			e.preventDefault();
			updateBookmark();
		}
	);

	$('#btnEditBookmark').click(
		function(e){
			e.preventDefault();
			updateBookmark();
		}
	);

	$('#btnDeleteBookmark').click(
		function(e){
			e.preventDefault();
			deleteBookMark();
		}

	);

	$('#addBookmark').click(
		function(e){
			e.preventDefault();
			addBookmark();
		}
	);
	$('#refreshBookmark').click(
		function(e){
			refresh(e);
		}
	);
	$('#searchBookmarkList').click(
		function(e) {
			searchList($('#searchListBox').val(), $('#list'));
		}
	);

	$("#login").click(
		function(e){
			navigateToBookmark(GOOGLE_LOGIN_URL);
		}
	);

	$('#reloadBookmarks').click(
		function(e){
			refresh(e);
		}
	);

}


function refresh(e){
	refresh();
	e.preventDefault();
}

function refresh(){
	location.reload();
}

function assignButtons(){
	
}

function addBookmark(title, url){

    $('#txtTitle').val(title);
    $('#txtURL').val(url);
    $('#txtLabels').val('');

    enableButton($('#btnAddBookmark'));
    disableButton($('#btnEditBookmark'));
    disableButton($('#btnDeleteBookmark'));

    $("div[forBookmarkUpdate='true']").hide();
}

function manageBookmark(){
	if(currentBookmark){
		editBookmark(currentBookmark);
	}else{
		chrome.tabs.query({'active': true}, function (tabs) {

		   	var url = tabs[0].url;
	    	var title = tabs[0].title;

			var bookmarkObj = findBookmarkByUrl(url);
			if(bookmarkObj === undefined){
				addBookmark(title, url);
			}else{
				editBookmark(bookmarkObj);
			}

		});

	}
}

/*Context menu*/
function createContextMenu(){

	$(document).contextmenu({
		delegate: ".hasMenu",
		preventSelect: true,
		taphold: true,
		menu: [
			{title: "Edit", cmd: "edit"},
			{title: "Delete", cmd: "delete"}
		],
		select: function(event, ui) {
			var $target = ui.target;
			switch(ui.cmd){
			case "delete":
				log("Delete clicked");
				break;
			case "edit":
				log("Edit clicked");
				break;
			}
		},
		beforeOpen: function(event, ui) {
			var $menu = ui.menu,
				$target = ui.target;
			$(document)
				.contextmenu("setEntry", "edit", "Edit")
				.contextmenu("setEntry", "delete", "Delete" );
			// Optionally return false, to prevent opening the menu now
		}

	});

}

/*Start downloading data from google bookmarks*/
function downloadBookmarks(){
	$.ajax(
		{
			url: GOOGLE_BOOKMARK_URL + "find",
			type: "GET",
			data: {output:"rss", num:"100000"}, 
			cache: false,
			dataType: "xml",
			success: function(xml){
            	processXMLData(xml);
        	}
		}
	);
	
}

/*Update the current bookmark*/
function updateBookmark(){
	$.ajax(
		{
			url: GOOGLE_BOOKMARK_URL + "mark",
			type: "POST",
			data: {
				sig : signature,
				bkmk : $('#txtURL').val(),
				title : $('#txtTitle').val(),
				labels : $('#txtLabels').val(),
				annotation : $('#txtAnnotation').val(),
				prev : '/mark'
			}, 
			cache: false,
			success: function(data, status){
            	refresh();
        	}
		}
	);
}

/*Delete current bookmark*/
function deleteBookMark(){

	$.ajax(
		{
			url: GOOGLE_BOOKMARK_URL + "mark",
			type: "POST",
			data: {dlq:currentBookmark.id, sig:signature}, 
			cache: false,
			success: function(){
				currentBookmark = undefined;
            	refresh();
        	}
		}
	);
	
	
}

/*Process the bookmarks xml document and put them in the right places*/
function processXMLData(xmlDoc){
	
	initBookmarks();
	signature = $(xmlDoc).find('signature').text();
	$(xmlDoc).find("item").each(
		function(){
			log("Bookmark title - " + $(this).find("title").text());
			var jsonBookmark = {};
			jsonBookmark.id = $(this).find("bkmk_id").text();
			jsonBookmark.url = $(this).find("link").text();
			jsonBookmark.title = $(this).find("bkmk_title").text();
			jsonBookmark.description = $(this).find("bkmk_annotation").text();
			jsonBookmark.timestamp = $(this).find("pubDate").text();
			jsonBookmark.labels = "";

			var labelCount = 0;
			$(this).find('bkmk_label').each(
				function(){
					jsonBookmark.labels += $(this).text() + ", ";
					addBookmarkToLabel($(this).text(), jsonBookmark);
					labelCount++;
				}
			);
			if(labelCount == 0){
				addBookmarkToLabel(unsorted, jsonBookmark);
			}

			bookmarks.push(jsonBookmark);
				
		}
	);
	
	// bookmarks = [];
	createTabs();
	
	if(bookmarks.length > 0){
		visualizeBookmarks();	
	}else{
		disableTab($('#cloudTab'));
		disableTab($('#treeTab'));
		disableTab($('#listTab'));

		$('#bookmarkTab').click();
	}
	
}

function disableTab(tabAnchor){
	$(tabAnchor).parent().addClass('veryDull');
	$(tabAnchor).bind('click', function(e){
        e.preventDefault();
        return false;
	});
}

/*Load data into graphs*/
function visualizeBookmarks(){

	var treeData = [];
	var cloudTags = [];
	var listData = [];

	for(labelKey in labelsMap){
	
		var treeEntry = {};
	
		treeEntry.label = labelKey;
		
		treeEntry.children = [];
		var bookmarks = labelsMap[labelKey];
		for(i = 0; i < bookmarks.length; i++){
			var bookmark = bookmarks[i];
			
			var labelData = {}; 
			labelData.label = bookmark.title;
			labelData.bookmark = bookmark;
			
			listData.push(labelData);
			if(labelKey != unsorted)
				treeEntry.children.push(labelData);
			else
				treeData.push(labelData);
		}
		
		if(labelKey != unsorted){
			treeData.push(treeEntry);
			
			var tag = {};
			tag.text = labelKey;
			tag.title = labelKey + '(' + bookmarks.length + ')';
			tag.weight = bookmarks.length;
			tag.link = "#";
			cloudTags.push(tag);

		}
		
	}
	
	/*Cloud tags*/
	$("#tagCloudCanvasContainer").jQCloud(
		cloudTags, 
		{styleClass:'jqCloudLink'}, 
		function onClick(e){
			e.preventDefault();
			log("Showing list for " + e.target.text);
			showListForLabel(e.target.text);

		}
	);
	
	/*Tree*/
	visualizeTreeData(treeData);
	
	/*List*/
	visualizeListData(listData);

	/*Current tab*/
	setupCurrentTabBookmark(cloudTags);
}

function setupCurrentTabBookmark(cloudTags){
	$( "#txtLabels" )
	 // don't navigate away from the field on tab when selecting an item
    .bind( "keydown", function( event ) {
        if ( event.keyCode === $.ui.keyCode.TAB &&
            $( this ).data( "ui-autocomplete" ).menu.active ) {
          event.preventDefault();
        }
      })
	.autocomplete(
		{
      		//source: Object.keys(labelsMap),
      		multiple: true,
      		minLength: 0,
        	source: function( request, response ) {
          		// delegate back to autocomplete, but extract the last term
          		response( $.ui.autocomplete.filter(Object.keys(labelsMap), extractLast( request.term ) ) );
        	},
      		focus: function() {
          		// prevent value inserted on focus
          		return false;
        	},
        	select: function( event, ui ) {
          		var terms = split( this.value );
          		// remove the current input
          		terms.pop();
          		// add the selected item
          		terms.push( ui.item.value );
          		
          		// add placeholder to get the comma-and-space at the end
          		terms.push( "" );
          		this.value = terms.join( ", " );
          		return false;
        	},
        	/*Max width hack*/
        	open: function(){
                $('.ui-autocomplete').css('width', '250px');
            },
            messages: {
        		noResults: '',
        		results: function() {}
    		}
    	}
    );

}

function visualizeListData(listData){
	clearBookmarksList();
	
	listData.sort(
		function(a, b){
			return a.label.localeCompare(b.label);
		}
	);
	
	for(i = 0; i < listData.length; i++){
		var linkTitle = listData[i].bookmark.description;
		if(linkTitle){
			linkTitle += '\n';
		}
		linkTitle += listData[i].bookmark.url;
		$('#list').append("<li class='listClass'><a bookmarkid='" + listData[i].bookmark.id + "' class='clickableList' href='javascript:void(0);' title='" + linkTitle + "' labels='" + listData[i].bookmark.labels + "'>" + listData[i].bookmark.title + "</a></li>");
	}

	$(document).on("contextmenu", ".clickableList", function(e){
   		var bookmarkId = $(e.currentTarget).attr('bookmarkid');
   		log("Selected bookmark id " + bookmarkId);
   		editBookmark(findBookmarkById(bookmarkId));
   		return false;
	});
	
	$('.clickableList').click(
		function(){
			var url = $(this).attr('title');
			navigateToBookmark(url);	
		}
	);
}

function findBookmarkById(bookmarkId){
	var results = bookmarks.filter(
		function(entry){
			return entry.id == bookmarkId;
		}
	);

	if(results){
		return results[0];
	}
}


function findBookmarkByUrl(bookmarkUrl){
	var results = bookmarks.filter(
		function(entry){
			return entry.url == bookmarkUrl;
		}
	);

	if(results){
		return results[0];
	}	
}

function visualizeTreeData(treeData){
	treeData.sort(
		function(a, b){
			if((a.children != null) && (b.children == null))
				return -1;
			else if((a.children == null) && (b.children != null))
				return 1;
			else
				return a.label.localeCompare(b.label);
			
		}
	);
	
	$('#bookmarksTree').bind(
		'tree.click',
		function(event) {
			if (event.node) {
				// node was selected
				var node = event.node;
				navigateToBookmark(node.bookmark.url);
			}
		}
	);
	
	
	$('#bookmarksTree').bind(
		'tree.contextmenu',
		function(event) {
			// The clicked node is 'event.node'
			$(document).contextmenu("close");
			var node = event.node;
			$('li').removeClass('hasMenu jqtree-selected');
			if(node.bookmark != null){
				log("Node selected for context node : " + node.bookmark.id);
				editBookmark(node.bookmark);

			}
		}
	);
	
	$('#bookmarksTree').tree({
            data: treeData
    });
}

function editBookmark(bookmark){
	$('#txtTitle').val(bookmark.title);
    $('#txtURL').val(bookmark.url);
	$('#txtLabels').val(bookmark.labels);
	$('#txtAnnotation').val(bookmark.description);
    
    bookmarkEdit = true;
    disableButton($('#btnAddBookmark'));
    enableButton($('#btnEditBookmark'));
    enableButton($('#btnDeleteBookmark'));

    $("div[forBookmarkUpdate='true']").show();

    $('#bookmarkTab')[0].click();

    currentBookmark = bookmark;
}

function disableButton(button){
	$(button).attr("disabled", "disabled");
}

function enableButton(button){
	$(button).removeAttr("disabled");  
}

function navigateToBookmark(urlto){
	log("navigating to " + urlto);
	chrome.tabs.create(
		{url : urlto}
	);
}

function initBookmarks(){
	labelsMap = {};
	signature = "";
}

/*Process the bookmark data*/
function addBookmarkToLabel(label, bookmark){
	if(!(label in labelsMap)){
		labelsMap[label] = [];
	}
	labelsMap[label].push(bookmark);
}

/*Create the tabs for different ways of navigating through bookmarks*/
function createTabs(){
	
	$('#tabs').organicTabs(
		{
			onChange : function(tabId){
				log("Currently selected tab " + tabId);
				if(tabId === 'currentTab'){
					manageBookmark();
				}
				if(!bookmarkEdit){
					currentBookmark = null;
				}
				bookmarkEdit = false;
			}
		}
	);
	$('#tabs').show();
}

function clearBookmarksList(){
	$('li.listClass').remove();
}

function clearBookmarksTree(){
	$('#bookmarksTree').children().remove();
}

function clearTagCloud(){
	$('span[id*=tagCloudCanvasContainer_word]').remove();
}

function split( val ) {
    return val.split( /,\s*/ );
}
function extractLast( term ) {
	return split( term ).pop();
}


jQuery.expr[':'].icontains = function(a, i, m) {
  return jQuery(a).text().toUpperCase()
      .indexOf(m[3].toUpperCase()) >= 0;
};

function searchList(text, element) {
	if(!text && 0===text.length){
		$(element).find("a").show();	
	}else{
		$(element).find("a").hide();
		if(text.indexOf("label:") != 0) {
			$(element).find("a:icontains(" + text + ")").show();
		}else{
			var labelToSearch = text.split('label:')[1];
			if(labelToSearch!=''){
				$("a[labels*='" + labelToSearch + "']").show();
			}else{
				$("a[labels='']").show();
			}
		}
	}
}


function showListForLabel(labelToSearch){
	$('#list').click();
	$('#searchListBox').val('label:' + labelToSearch);
	$('#searchBookmarkList').click();
	$('#listTab')[0].click();
}


